import { defineStore } from 'pinia'
import { mergeDeep } from '@/utils'
import { getMessageList } from '@/assets/api/message'
import useUser from '@/store/user.js'
import dayjs from 'dayjs'

const MAX_LENGTH = 300

const useChannel = defineStore('channel', {
  state: () => {
    return {
      // 当前对话
      dialog: null,
      channelList: [],
      channelMsgMap: new Map(),
      // 成员
      membersMap: new Map(),
      memberAvatarMap: new Map(),
      // 消息统计
      countStatisticsMap: new Map(),
      mentionMeMsgList: [],
    }
  },
  persist: [
    {
      paths: ['dialog'],
    },
  ],
  getters: {
    // 当前频道ID
    channelId: (state) => {
      return state.dialog ? state.dialog.id : null
    },
    // 频道所有者
    channelManager: (state) => {
      return state.membersMap.get(state.channelId)?.find((i) => i.manager === 1) || null
    },
    // 是否本频道管理员
    isManager: (state) => {
      const userStore = useUser()
      return (
        state.channelManager?.userId === userStore.userId ||
        state.membersMap
          .get(state.channelId)
          ?.filter((i) => i.manager === 2)
          .some((i) => i.userId === userStore.userId)
      )
    },
    members: (state) => {
      return state.membersMap.get(state.channelId) || []
    },
    userAvatarMap: (state) => {
      return state.memberAvatarMap
    },
    // 当前对话消息列队
    currentDialogMsgList: (state) => {
      if (state.dialog) {
        return state.channelMsgMap.get(state.dialog ? state.dialog.id : null)
      } else {
        return []
      }
    },
    // TODO 临时改成取 rootMsgCount, 等功能完善再还原成 mentionCount
    mentionCount: (state) => {
      return Array.from(state.countStatisticsMap.values()).reduce((count, item) => {
        count += item.rootMsgCount
        return count
      }, 0)
    },
    // 提及消息ID
    mentionMessageId: (state) => {
      if (!state.dialog) return null
      return null
      // const messageList = state.channelMsgMap.get(state.dialog.id)
      // return messageList.find((i) => i.isMention && !i.isView).id
    },
    // 当前对话权限
    dialogExt: (state) => {
      return state.dialog?.ext || {}
    },
  },
  actions: {
    // 设置频道列表
    setChannelList(list) {
      // 拆分置顶和非置顶
      const mergeList = list.map((item) => {
        item.createTimeStamp = dayjs(item.createTime).valueOf()
        item.lastMsgTimeStamp = dayjs(item.lastMsgTime).valueOf() || null
        return item
      })
      mergeList.sort((a, b) => {
        if (a.lastMsgTimeStamp && b.lastMsgTimeStamp) {
          return b.lastMsgTimeStamp - a.lastMsgTimeStamp
        } else if (a.lastMsgTime) {
          return -1
        } else if (b.lastMsgTime) {
          return 1
        } else {
          return b.createTimeStamp - a.createTimeStamp
        }
      })
      const top = mergeList.filter((i) => i.pinnedFlag === 1)
      const notTop = mergeList.filter((i) => i.pinnedFlag === 2 || i.pinnedFlag === null)
      this.channelList = top.concat(notTop)
    },
    setMentionMeMsgList(list) {
      this.mentionMeMsgList = list
    },
    addMentionMeMsg(message) {
      this.mentionMeMsgList.push(message)
    },
    removeMentionMeMsg(messageId) {
      const index = this.mentionMeMsgList.findIndex((i) => messageId === i.msgId)
      this.mentionMeMsgList.splice(index, 1)
    },
    addChannelList(channel) {
      this.channelList.push(channel)
    },
    updateChannel(channelId, key, value) {
      const channel = this.channelList.find((i) => i.id === channelId)
      channel[key] = value
    },
    removeChannel(channelId) {
      const index = this.channelList.findIndex((i) => i.id === channelId)
      this.channelList.splice(index, 1)
      this.removeChannelMsgMap(channelId)
      this.removeMembersMap(channelId)
    },
    // 置顶消息
    topMessage(data, isTop = true) {
      const channel = this.channelList.find((i) => i.id === data.channelId)
      if (isTop) {
        channel.msgTops[0] = data
      } else {
        const index = channel.msgTops.findIndex((i) => i.id === data.id)
        channel.msgTops.splice(index, 1)
      }
    },
    // 更新频道成员信息
    updateMember(member) {
      const index = this.members.findIndex((i) => i.id === member.id)
      // 群主放到最前面
      if (member.manager === 1) {
        this.members.splice(index, 1)
        this.members.unshift(member)
      } else if (member.manager === 2) {
        this.members.splice(index, 1)
        this.members.splice(1, 0, member)
      } else {
        this.members.splice(index, 1, member)
      }
    },
    // 频道放到最顶部
    topChannel(channelId, pinnedFlag) {
      const ChannelIndex = this.channelList.findIndex((i) => i.id === channelId)
      if (pinnedFlag === 1) {
        const channel = this.channelList.splice(ChannelIndex, 1)[0]
        this.channelList.unshift(channel)
      } else {
        const index = this.channelList.findIndex((i) => i.pinnedFlag === 2)
        const channel = this.channelList.splice(ChannelIndex, 1)[0]
        this.channelList.splice(index, 0, channel)
      }
    },
    // 第一个参数传消息数据
    updateMessage({ channelId, id }, key, value) {
      let message = null
      const msgList = this.channelMsgMap.get(channelId)
      message = msgList && msgList.find((i) => i.id === id)
      if (message) {
        let obj = message
        key.split('.').forEach((item, index, { length }) => {
          if (index === length - 1) {
            obj[item] = value
          } else {
            obj = obj[item]
          }
        })
        // 如果在置顶消息中,则更新置顶消息
        const channel = this.channelList.find((i) => i.id === message.channelId)
        const topMsgIndex = channel.msgTops.findIndex((i) => i.messageData.id === id)
        if (topMsgIndex !== -1) {
          channel.msgTops.splice(topMsgIndex, 1, message)
        }
      }
    },
    removeMessage(message) {
      const msgList = this.channelMsgMap.get(message.channelId)
      const index = msgList.findIndex((i) => i.id === message.id)
      msgList.splice(index, 1)
      // 如果删除的是最后一条消息,更新 lastMessage
      if (index === msgList.length) {
        this.dialog.lastMessage = msgList[msgList.length - 1]
      }
    },
    // 设置当前对话
    setDialog(dialog) {
      this.dialog = dialog
      // this.setMsgCache(dialog.id, () => this.currentDialogMsgList, this.addChannelMsg)
    },
    // 更新当前对话属性
    updateDialog(channelId, key, value) {
      const channel = this.channelList.find((i) => i.id === channelId)
      if (channel) {
        channel[key] = value
      }
    },
    // 添加频道成员映射
    addMembersMap(channelId, members) {
      this.membersMap.set(channelId, members)
      if (members && members.length > 0) {
        members.forEach((item) => {
          this.memberAvatarMap.set(item.userId, item.avatar)
        })
      }
    },
    // 移除频道成员映射
    removeMembersMap(channelId) {
      this.membersMap.delete(channelId)
    },
    // 添加对话消息
    async addChannelMsg(message) {
      const channel = this.channelList.find((i) => i.id === message.channelId)
      if (!this.channelMsgMap.has(message.channelId)) {
        const res = await getMessageList({
          channelId: message.channelId,
          pageNum: 1,
          pageSize: 50,
          msgIdBefore: channel?.lastMessage?.id,
        })
        this.addChannelMsgMap(message.channelId, reactive(res.code === 200 ? res.data : []))
      }
      const list = this.channelMsgMap.get(message.channelId)
      const oldMessage = list.find((i) => (message.uuid && i.uuid === message.uuid) || (i.id && i.id === message.id))
      const oldMentionMe = oldMessage ? oldMessage.metaData.status.mentionMe : null
      const oldReadFlag = oldMessage ? oldMessage.metaData.status.readFlag : null
      const messageVal = toValue(message)
      if (oldMessage) {
        delete messageVal.clientFiles
        mergeDeep(oldMessage, messageVal)
      } else {
        // 当频道的 lastMessage 和消息列队中的相等时，才继续插入
        if (!list.length || (channel?.lastMessage && channel?.lastMessage.id === list[list.length - 1].id)) {
          list.push(messageVal)
        }
        this.updateDialog(message.channelId, 'lastMessage', messageVal)
      }
      // 更新数量
      if (messageVal.metaData.status.readFlag) {
        if (oldMessage && !oldReadFlag) {
          if (oldMentionMe) {
            // 提及数量更新
            this.updateCount('mentionCount', message.channelId, false)
          }
          // 未读消息数量更新
          this.updateCount('rootMsgCount', messageVal.channelId, false)
        }
      } else {
        if (messageVal.metaData.status.mentionMe) {
          this.updateCount('mentionCount', message.channelId, true)
          this.addMentionMeMsg({
            msgId: messageVal.id,
            topicFlag: false,
          })
        }
        this.updateCount('rootMsgCount', messageVal.channelId, true)
      }
    },
    addChannelMsgList(msgList, push = true) {
      const list = this.channelMsgMap.get(this.channelId)
      push ? list.push(...msgList) : list.unshift(...msgList)
    },
    // 添加频道映射
    addChannelMsgMap(channelId, msgList = []) {
      this.channelMsgMap.set(channelId, msgList)
    },
    // 删除频道映射
    removeChannelMsgMap(channelId) {
      this.channelMsgMap.delete(channelId)
    },
    // 设置统计映射
    setMsgStatisticsMap(data) {
      data.forEach((item) => {
        this.setMsgStatistics(item.channelId, item)
      })
    },
    setMsgStatistics(channelId, data) {
      this.countStatisticsMap.set(channelId, data)
    },
    // 更新文件状态
    updateFileStatus(message) {
      let msg
      msg = this.channelMsgMap.get(message.channelId).find((i) => i.id === message.msgId)
      const list = msg?.clientFiles || msg.files
      const file = list.find((i) => i.uuid === message.uuid)
      mergeDeep(file, message)
    },
    // TODO 临时控制提醒数量的方法，将来添加跳转到提醒消息的功能
    updateCount(key, channelId, add = true) {
      if (!this.countStatisticsMap.has(channelId)) {
        this.countStatisticsMap.set(channelId, { [key]: 0 })
      }
      if (add) {
        this.countStatisticsMap.get(channelId)[key]++
      } else if (this.countStatisticsMap.get(channelId)[key] > 0) {
        this.countStatisticsMap.get(channelId)[key]--
      }
    },
  },
})

export default useChannel
